﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;


namespace System
{
    /// <summary>
    /// Common extensions of <see cref="Enum"/>.
    /// </summary>
    public static class EnumExtensions
    {
        /// <summary>
        /// Indicates whether the specified enum value and the specified int have the same value.
        /// </summary>
        /// <param name="enum">The enum to test.</param>
        /// <param name="value">The int value to compare to the <paramref name="enum"/>.</param>
        /// <returns>true if the value parameter is the same as the value of <paramref name="enum"/>;othervise, false.</returns>
        public static bool Equals(this Enum @enum, int value)
        {
            try
            {
                return @enum.IntValue() == value;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// Indicates whether the specified enum value and the specified byte have the same value.
        /// </summary>
        /// <param name="enum">The enum to test.</param>
        /// <param name="value">The byte value to compare to the <paramref name="enum"/>.</param>
        /// <returns>true if the value parameter is the same as the value of <paramref name="enum"/>;othervise, false.</returns>
        public static bool Equals(this Enum @enum, byte value)
        {
            try
            {
                return @enum.ByteValue() == value;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// Indicates whether the specified enum value and the specified byte have the same value(Ignore case during the comparison).
        /// </summary>
        /// <param name="enum">The enum to test.</param>
        /// <param name="value">The byte value to compare to the <paramref name="enum"/>.</param>
        /// <returns>true if the value parameter is the same as the value of <paramref name="enum"/>;othervise, false.</returns>
        public static bool Equals(this Enum @enum, string value)
        {
            if (value.IsNullOrBlank())
            {
                return false;
            }
            try
            {
                return @enum.ToString().ToLower() == value.TrimBlank().ToLower();
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// Returns the int value of the specified <paramref name="enum"/>.
        /// </summary>
        /// <param name="enum">The enum to convert.</param>
        /// <returns>The int value of the current <paramref name="enum"/></returns>
        public static int IntValue(this Enum @enum)
        {
            return Convert.ToInt32(@enum);
        }
        /// <summary>
        /// Returns the byte value of the specified <paramref name="enum"/>.
        /// </summary>
        /// <param name="enum">The enum to convert.</param>
        /// <returns>The byte value of the current <paramref name="enum"/></returns>
        public static byte ByteValue(this Enum @enum)
        {
            return Convert.ToByte(@enum);
        }

        /// <summary>
        /// 获取枚举的描述属性值，当描述属性没有时，直接返回名称
        /// </summary>
        /// <param name="enumValue">枚举名称</param>
        /// <returns></returns>
        public static string GetEnumDesc(Enum em)
        {
            string name = em.ToString();
            FieldInfo field = em.GetType().GetField(name);
            object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);    //获取描述属性
            if (objs == null || objs.Length == 0)    //当描述属性没有时，直接返回名称
                return name;
            DescriptionAttribute descriptionAttribute = (DescriptionAttribute)objs[0];
            return descriptionAttribute.Description;
        }
        /// <summary>
        /// 获取枚举的描述属性值，当描述属性没有时，直接返回名称
        /// </summary>
        /// <param name="enumValue">枚举名称</param>
        /// <returns></returns>
        public static string GetEnumDesc(string em)
        {
            string name = em.ToString();
            FieldInfo field = em.GetType().GetField(name);
            object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);    //获取描述属性
            if (objs == null || objs.Length == 0)    //当描述属性没有时，直接返回名称
                return name;
            DescriptionAttribute descriptionAttribute = (DescriptionAttribute)objs[0];
            return descriptionAttribute.Description;
        }
        /// <summary>
        /// 获取枚举的描述属性值，当描述属性没有时，直接返回名称
        /// </summary>
        /// <param name="enumValue"></param>
        /// <returns></returns>
        public static string GetEnumDesc<T>(this int status)
        {
            string name = Enum.GetName(typeof(T), status);
            var em = (T)Enum.Parse(typeof(T), name);
            FieldInfo field = em.GetType().GetField(name);
            object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);    //获取描述属性
            if (objs == null || objs.Length == 0)    //当描述属性没有时，直接返回名称
                return name;
            DescriptionAttribute descriptionAttribute = (DescriptionAttribute)objs[0];
            return descriptionAttribute.Description;
        }
        /// <summary>
        /// 根据枚举的值获取枚举名称
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="status">枚举的值</param>
        /// <returns></returns>
        public static string GetEnumName<T>(this int status)
        {
            return Enum.GetName(typeof(T), status);
        }
        /// <summary>
        /// 获取枚举名称集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static string[] GetNamesArr<T>()
        {
            return Enum.GetNames(typeof(T));
        }
        /// <summary>
        /// 将枚举转换成字典集合
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <returns></returns>
        public static Dictionary<string, int> GetEnumDic<T>()
        {

            Dictionary<string, int> resultList = new Dictionary<string, int>();
            Type type = typeof(T);
            var strList = GetNamesArr<T>().ToList();
            foreach (string key in strList)
            {
                string val = Enum.Format(type, Enum.Parse(type, key), "d");
                resultList.Add(key, int.Parse(val));
            }
            return resultList;
        }
        /// <summary>
        /// 将枚举转换成字典
        /// </summary>
        /// <typeparam name="TEnum"></typeparam>
        /// <returns></returns>
        public static Dictionary<string, int> GetDic<TEnum>()
        {
            Dictionary<string, int> dic = new Dictionary<string, int>();
            Type t = typeof(TEnum);
            var arr = Enum.GetValues(t);
            foreach (var item in arr)
            {
                dic.Add(item.ToString(), (int)item);
            }

            return dic;
        }


    }
}
